/* 动态规划，计算是否可由A数组中的元素相加，得到B中的元素 */

#include<iostream>
#include<algorithm>
#include<list>
using namespace std;

int main(void)
{
	constexpr int N = 5;
	constexpr int M = 4;

	int a[N] = { 1, 5, 7, 10, 21 };
	int b[M] = { 2, 4, 17, 8 };
	constexpr int BMAX = 17;

	bool bCanAFormB[BMAX + 1]{ false };
	list<int> listValueInA[BMAX + 1];

	bCanAFormB[0] = true;		//0不需要组合，可以直接得到
	for (int i = 0; i < N; i++)
	{
		for (int j = BMAX; j > 0; j--)
		{
			if (!bCanAFormB[j])
			{
				int leftJ = j - a[i];
				if (leftJ >= 0 && bCanAFormB[leftJ])
				{
					bCanAFormB[j] = true;
					listValueInA[j].assign(listValueInA[leftJ].begin(), listValueInA[leftJ].end());
					listValueInA[j].push_back(a[i]);
				}
			}
		}
	}

	for (int i = 0; i < M; i++)
	{
		int value = b[i];

		if (!bCanAFormB[value])
		{
			cout << "no\n";
		}
		else
		{
			cout << "yes. " << value << " = ";
			for_each(listValueInA[value].begin(), listValueInA[value].end(), [](int e) {cout << e << " "; });
			cout << endl;
		}
	}
}
